﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HR60_PanelSoft.Model;

namespace HR60_PanelSoft.Service
{
    //GC: [g1]执行业务约束[PanelService]@s9
    //GC: [g2]负载的外部信号关联问题[PanelService]
    //GC: [g3]面板删除逻辑[PanelService]
    //GC: [g4]面板数量上限检测[PanelService]
    //GC: [g5]面板删除逻辑增加智能终端逻辑[PanelService]
    //GC: [g6]bug2608[PanelService]
    //GC: [g7]opt:优化所有删除动作[PanelService]

	public class PanelService : CommonService
	{
        /* [g1.s7] Panel当前所属的Net【慎用】 */
        /*
         * [慎用]该字段只用来服务于IsCanNew方法，且在append更新。         
         */
        protected static Model.Net CurNet = null;
        /* end of [g1.s7] */

        /* [g1.s1] */
        /*
         * 初始化约束因子 
         */
        protected static int MaxPnlsInNet = 32;
        protected static int MaxNetGateInNet = 1;


        public static bool IsCanNew(HR60_PanelSoft.Model.BaseModel.RefModel ins)
        {
            bool rst = true;
            if (ins is Model.Net)
            {
                if (proj.nets.Count >= 8)
                {
                    return false;
                }
            }
            /*[g1.s4] 在判断是否可创新时，区别对待网关类型 */
            else if (ins is Model.Panel)
            {

                /* [g4.s1] */

                if (CurNet.panels.Count >= 32)
                {
                    return false;
                }

                /* end of [g4.s1] */

                /* 判断网关 */
                if (((Model.Panel)ins).type.name == "网关")
                {
                    foreach (Panel p in CurNet.panels)
                    {
                        if ("网关" == p.type.name)
                            return false;
                    }
                }
            }
           /* end of [g1.s4] */
           return rst;
        }

        /* end of [g1.s1] */
		// 保存
		public static void save(Panel source, Panel dto)
		{
			source.name = dto.name;
			source.index = dto.index;
			source.style = dto.style;
			source.eplusType = dto.eplusType;

            //GC: 修改PanelService服务，应该增加负载服务
            /* 保存负载 */
            
            //if (source.loadPins.Count != dto.loadPins.Count) /* 确保负载数量匹配 */
            //    return;
            //for (int i = 0; i < source.loadPins.Count; i++)
            //{
            //    source.loadPins[i] = dto.loadPins[i];
            //}
		}
		
		// 添加
		public static void append(Panel panel, HR60_PanelSoft.Model.Net net)
		{
            /* [g1.s8] 传递当前网络 */
            CurNet = net;
            /* end of [g1.s8] */

            /* [g4.s2] */
            /* [g1.s2]对新建操作执行约束 */
            
            //if (!IsCanNew(net))
            //{
            //    View.ViewUtils.showAlert("一个网络中最多设置" + MaxPnlsInNet .ToString() + "个面板！" +
            //        " 当前面板数为" + net.panels.Count.ToString() + "个！\r\n");
            //    RestrictErr = true; /* 设置约束错误标记 */
            //    return;
            //}
            ///* [g1.s5] 在追加面板时，区别对待网关面板 */
            //else if(!IsCanNew(panel))
            if(!IsCanNew(panel))
            {
                if (panel.type.name == "网关")
                    View.ViewUtils.showAlert("一个网络中最多设置" + MaxNetGateInNet.ToString() + "个网关！" +
                        " 当前网关数为" + MaxNetGateInNet.ToString() + "个！\r\n");
                else
                    View.ViewUtils.showAlert("一个网络中最多设置" + MaxPnlsInNet.ToString() + "个面板！" +
                        " 当前面板数为" + MaxPnlsInNet.ToString() + "个！\r\n");
                RestrictErr = true; /* 设置约束错误标记 */
                return;
            }
            /* end of [g1.s5] */
            else
                RestrictErr = false;
            /* end of [g1.s2] */
            /* end of [g4.s2] */
			net.panels.Add (panel);
		}
		public static Panel append(PanelType type, HR60_PanelSoft.Model.Net net)
		{
			Panel panel = PanelTypeService.getPanelCreator().create(type);
			panel.index = PanelService.newPanelId(net);
            /* [g6.s1]bug2608 修改面板名称 */
            panel.name = "面板" + panel.index + "-" + panel.type.name;
            /* end of [g6.s1] */

            /* [g1.s9] 传递当前网络 */
            CurNet = net;
            /* end of [g1.s9] */
            /* [g4.s3] */

            /* [g1.s3]对新建操作执行约束 */

            //if (!IsCanNew(net))
            //{
            //    View.ViewUtils.showAlert("一个项目中最多设置" + MaxNetGateInNet.ToString() + "个网络！" +
            //        " 当前网络数为" + proj.nets.Count.ToString() + "个！\r\n");
            //    RestrictErr = true; /* 设置约束错误标记 */
            //    return null;
            //}
            ///* [g1.s6] 在追加面板时，区别对待网关面板 */
            //else if (!IsCanNew(panel))
            if(!IsCanNew(panel))
            {
                if (panel.type.name == "网关")
                    View.ViewUtils.showAlert("一个网络中最多设置" + MaxNetGateInNet.ToString() + "个网关！" +
                        " 当前网关数为" + MaxNetGateInNet.ToString() + "个！\r\n");
                else
                    View.ViewUtils.showAlert("一个网络中最多设置" + MaxPnlsInNet.ToString() + "个面板！" +
                        " 当前面板数为" + MaxPnlsInNet.ToString() + "个！\r\n");
                RestrictErr = true; /* 设置约束错误标记 */
                return null;
            }
            /* end of [g1.s6] */
            else
                RestrictErr = false;
            /* end of [g1.s3] */

            /* end of [g4.s3] */
			net.panels.Add(panel);
			return panel;
		}

		// 删除

        /* [g5.s2]优化删除操作，增加删除结果返回 */
		//public static void remove(Panel panel)
        public static bool remove(Panel panel)
		{
            /* [g5.s1]检测是否影响智能终端逻辑 */
            if (panel.type.name == "HK-60Q6CW" || panel.type.name == "HK-50Q6CW" )
            {
                /* 1. 检索网络中是否绑定了智能终端 */
                List<string> tempZNZDId = new List<string>();
                foreach (DeviceGroup dg in proj.deviceGroups)
                {
                    foreach (Device d in dg.devices)
                    {
                        if (d.type.name == "智能终端（灯光窗帘）" || d.type.name == "智能终端（全部功能）")
                            tempZNZDId.Add(d.uuid);
                    }
                }
                if (tempZNZDId.Count > 0) /* 设备中存在智能终端 */
                {
                    int tempBindNum = 0;
                    foreach (Net n in proj.nets)
                    {
                        foreach (HR60_PanelSoft.Model.Panel pnl in n.panels) 
                        {
                            if (pnl.type.name == "HK-60Q6CW" || pnl.type.name == "HK-50Q6CW")
                            {
                                if (tempZNZDId.Exists(x => x == pnl.m485Pin.connectedDevice)) 
                                    tempBindNum++;
                                if (tempBindNum > 0) /* 项目中存在智能终端绑定 */
                                {
                                    /* 2. 确保当前子网内Q6面板数目大于1*/
                                    int tempQ6Num = 0;
                                    foreach (HR60_PanelSoft.Model.Panel p in CurNet.panels)
                                    {
                                        if (p.type.name == "HK-60Q6CW" || p.type.name == "HK-50Q6CW")
                                            tempQ6Num++;
                                        if (tempQ6Num > 1)
                                            break;
                                    }

                                    /* 
                                     * 1. 如果网络中绑定了智能终端
                                     * 2. 如果当前子网内的Q6面板只有1个
                                     * 则无法删除面板
                                     */
                                    if (tempQ6Num < 2)  
                                    {
                                        View.ViewUtils.showAlert("项目中存在智能终端负载，请确保所有子网中至少包含1个Q6面板。\r\n "+
                                            "或，先解除智能终端负载后，再尝试删除该面板。");
                                        return false;
                                    }


                                    
                                }
                            }
                        }
                    }
                    

                }

                

                
            }
            /* end of [g5.s1] */


            /* [g3.s1] 卸载负载关系 */
			// 卸载负载关系
            //foreach (Pin pin in panel.loadPins)
            //{
            //    if (pin.isMainPin) 
            //    {
            //        // 卸载场景关系
            //        resetSceneByRemovePin (pin);

            //        pin.getConnectedDevice().connectedPins.Clear ();
            //        pin.isMainPin = false;
            //    }
            //    pin.connectedDevice = null;
            //}

            foreach (Pin p in panel.loadPins)
            {
                if (p.connectedDevice != null)
                {
                    resetSceneByRemovePin(p);
                    p.getConnectedDevice().connectedPins.Clear();
                    p.isMainPin = true;
                }
            }

            /* end of [g3.s1] */

            /* [g3.s2] 卸载485线路 */
            //// 卸载485线路
            //if (panel.type.hasM485Model && panel.m485Pin.connectedDevice != null)
            //{
            //    // 卸载场景关系
            //    resetSceneByRemovePin (panel.m485Pin);

            //    panel.m485Pin.getConnectedDevice().connectedPins.Clear ();
            //    panel.m485Pin.connectedDevice = null;

                
            //    panel.m485Pin.isMainPin = false;
            //}

            if (panel.type.hasM485Model && panel.m485Pin.connectedDevice != null)
            {


                resetSceneByRemovePin(panel.m485Pin);
                panel.m485Pin.getConnectedDevice().connectedPins.Clear();
                panel.m485Pin.connectedDevice = null;
                panel.m485Pin.isMainPin = true;
            }

            /* end of [g3.s2] */
			// 删除
			foreach (HR60_PanelSoft.Model.Net net in proj.nets) 
			{
				if (net.panels.Contains (panel))
					net.panels.Remove (panel);
			}

            return true;
		}

		// 卸载场景关系
		private static void resetSceneByRemovePin(Pin pin)
		{
            /* [g7.s1] */

            //foreach (Scene scene in proj.scenes)
            //{
            //    foreach(SceneEvent evet in scene.events)
            //    {
            //            scene.events.Remove (evet);
            //    }
            //}
            foreach (Scene scene in proj.scenes)
            {
                DeleteMember<SceneEvent>(scene.events, null, new CompareDele<SceneEvent>(
                   (SceneEvent T1,SceneEvent T2) => {
                       return T1.device == pin.connectedDevice;
                   }));
            }

            /* end of [g7.s1] */


		}

		public static int newPanelId(HR60_PanelSoft.Model.Net net)
		{
			for (int id = 1; id < 512; id++)
			{
				bool findFlag = false;
				for (int i = 0; i < net.panels.Count; i++)
				{
					if (id == net.panels[i].index)
					{
						findFlag = true;
						break;
					}
				}
				if (!findFlag) return id;
			}
			return -1;
		}


        /* [g2.s1] 根据pin获取到对外部信号的响应值 */
        /// <summary>
        /// 根据pin获取到对外部信号的响应值
        /// </summary>
        /// <param name="p">Pin实例</param>
        /// <returns>返回响应值：0-不响应，1-响应开，2-响应关</returns>
        public static int getPinSignalRel(Pin p)
        {
            int rst = -1;
            Panel pnl = p.getPanel();
            
            if (pnl == null)
            {
                //GCERR:
                return -1;
            }
            if (p.connectedDevice == null)
                return -1;
            SceneEvent e = pnl.signal.localScene.findEventByDevice(p.connectedDevice);

            /* 
             * SceneEvent的attrs绑定是：1-开，0-关 
             * 协议是：0-不响应，1-开，2-关
             */
            if (e.attrs.Count < 1) //不响应
                return 0;
            if (e.attrs.Count != 1)
            {
                //GCERR:
                return -1; //错误
            }
            if (e.attrValueKeys[0] == "1")
                rst = 1;
            else if (e.attrValueKeys[0] == "0")
                rst = 2;
            return rst;
        }
        /* end of [g2.s1] */
	}
}
